package com.david.equipment.service.impl;

import com.david.common.exception.EquipmentException;
import com.david.common.utils.PageResult;
import com.david.equipment.common.constant.TacticsType;
import com.david.equipment.mapper.DeviceMapper;
import com.david.equipment.mapper.TacticsMapper;
import com.david.equipment.pojo.entity.*;
import com.david.equipment.pojo.vo.*;
import com.david.equipment.service.TacticsService;
import com.david.system.mapper.UserMapper;
import com.david.system.pojo.Entity.UserEntity;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

@Service
public class TacticsServiceImpl implements TacticsService {
    @Autowired
    private TacticsMapper tacticsMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private DeviceMapper deviceMapper;

    @Override
    @Transactional
    public void addTactics(TacticsVO tacticsVO) {
        tacticsVO.setCreateTime(LocalDateTime.now());
        String username = SecurityContextHolder.getContext().getAuthentication().getName();
        UserEntity currentUser = userMapper.selectUserByUsername(username);
        tacticsVO.setCreateby(currentUser.getId());
        tacticsVO.setStatus("0");
        //自动生成策略名称，润滑/保养/点检 LC/MT/SC230620001
        String prefix = Objects.equals(tacticsVO.getType(), "lude") ? "LC" : (Objects.equals(tacticsVO.getType(), "maintain") ? "MT" : "SC");
        String ludeToday = prefix.concat(LocalDate.now().format(DateTimeFormatter.ofPattern("yyMMdd")));
        TacticsEntity tacticsEntity = new TacticsEntity();
        tacticsEntity.setCode(ludeToday);
        tacticsEntity.setType(TacticsType.lude.toString());
        List<TacticsEntity> tacticsEntities = tacticsMapper.selectTactics(tacticsEntity);
        if (tacticsEntities.isEmpty()) {
            tacticsVO.setName(ludeToday.concat("001"));
        } else {
            String substring = tacticsEntities.get(tacticsEntities.size() - 1).getCode().substring(8);
            tacticsVO.setCode(ludeToday.concat(String.format("%03d", Integer.parseInt(substring) + 1)));
        }
        // 根据循环周期，添加cronExpression表达式
//        String loopPeriod = tacticsVO.getLoopPeriod();
//        int loopPeriodNum = Integer.parseInt(loopPeriod.substring(0, loopPeriod.length() - 1));
//        String loopUnit = loopPeriod.substring(loopPeriod.length() - 1);
//        switch (loopUnit) {
//            case "D":
//                tacticsVO.setCronExpression("0 0 0 1/" + loopPeriodNum + " * ?");
//                break;
//            case "W":
//                if (loopPeriodNum > 7) throw new EquipmentException("循环周期不能超过7天");
//                tacticsVO.setCronExpression("0 0 0 ? * " + loopPeriodNum);
//                break;
//            case "M":
//                if (loopPeriodNum > 31) throw new EquipmentException("循环周期不能超过31天");
//                tacticsVO.setCronExpression("0 0 0 " + loopPeriodNum + " * ?");
//                break;
//        }
        tacticsMapper.insertTactics(tacticsVO);
        if (!tacticsVO.getDevicelist().isEmpty()) {
            tacticsMapper.insertTacticsDevices(tacticsVO);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateTactics(TacticsVO tacticsVO) {
        tacticsVO.setUpdateTime(LocalDateTime.now());
        String username = SecurityContextHolder.getContext().getAuthentication().getName();
        UserEntity currentUser = userMapper.selectUserByUsername(username);
        tacticsVO.setUpdateby(currentUser.getId());

        tacticsMapper.updateTactics(tacticsVO);
        if (!tacticsVO.getDevicelist().isEmpty()) {
            List<Integer> oldIds = new ArrayList<>();
            tacticsMapper.selectTacticsDevicesByTacticsId(tacticsVO.getId()).forEach(
                    device -> oldIds.add(device.getDeviceId())
            );
            for (TacticsDeviceEntity device : tacticsVO.getDevicelist()) {
                device.setTacticsId(tacticsVO.getId());
                if (oldIds.contains(device.getDeviceId())) {
                    tacticsMapper.updateTacticsDevice(device); //原设备表中有则更新
                    oldIds.remove(device.getDeviceId()); //列表中移除
                } else {
                    tacticsMapper.insertTacticsDevicesByEntity(device); //原设备表中没有则新增
                }
            }
            if (!oldIds.isEmpty()){
                tacticsMapper.deleteTacticsDeviceByIds(tacticsVO.getId(),oldIds);
            }

        }
    }

    @Override
    public PageResult getTactics(CommonVO commonVO, String type) {
        PageHelper.startPage(commonVO.getPage(), commonVO.getPageSize());
        TacticsEntity tacticsEntity = new TacticsEntity();
        tacticsEntity.setType(type);
        if (commonVO.getId() != null) {
            tacticsEntity.setId(commonVO.getId());
        }
        //自动生成策略名称，润滑/保养/点检 LC/MT/SC230620001
        // String ludeToday = "LC".concat(LocalDate.now().format(DateTimeFormatter.ofPattern("yyMMdd")));
        List<TacticsEntity> list = tacticsMapper.selectTactics(tacticsEntity);
        PageResult pageResult = new PageResult();
        pageResult.setRecords(list);
        pageResult.setTotal(list.size());
        return pageResult;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addProject(TacticsProjectVO tacticsProjectVO) {
        // 检查必填信息
        if (tacticsProjectVO.getName() == null || tacticsProjectVO.getType() == null || tacticsProjectVO.getItemsList().isEmpty()) {
            throw new EquipmentException("项目信息不能为空");
        }
        tacticsMapper.inertProject(tacticsProjectVO);
        for (TacticsProjectItems item : tacticsProjectVO.getItemsList()) {
            item.setProjectId(tacticsProjectVO.getId());
        }
        tacticsMapper.insertProjectItems(tacticsProjectVO.getItemsList());
    }

    @Override
    public List<TacticsProjectVO> getProject(String type, Integer deptId) {
        List<TacticsProject> tacticsProjects = tacticsMapper.selectProject(type, deptId);
        List<TacticsProjectVO> tacticsProjectVOS = new ArrayList<>();
        for (TacticsProject project : tacticsProjects) {
            TacticsProjectVO projectVO = new TacticsProjectVO();
            BeanUtils.copyProperties(project, projectVO);
            Optional<List<TacticsProjectItems>> items = Optional.ofNullable(tacticsMapper.selectProjectItems(projectVO.getId()));
            items.ifPresent(projectVO::setItemsList);
            tacticsProjectVOS.add(projectVO);
        }
        return tacticsProjectVOS;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void editProject(TacticsProjectVO tacticsProjectVO) {
        TacticsProject project = new TacticsProject();
        BeanUtils.copyProperties(tacticsProjectVO, project);
        System.out.println(project);
        tacticsMapper.updateProject(project);
        for (TacticsProjectItems item : tacticsProjectVO.getItemsList()) {
            tacticsMapper.updateProjectItems(item);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean delProject(Integer id) {
        //查询是否在用
        List<TacticsEntity> tacticsEntities = tacticsMapper.selectTactics(TacticsEntity.builder().projectId(id).build());
        if (!tacticsEntities.isEmpty()) return false;
        tacticsMapper.deleteProject(id);
        tacticsMapper.deleteProjectItems(id);
        return true;
    }

    @Override
    public List<TacticsHisTaskVO> getHisTask(TacticsHisTaskEntity hisTask) {
        List<TacticsHisTaskEntity> tasks = tacticsMapper.selectTacticsHisTask(hisTask);
        List<TacticsHisTaskVO> taskVOList = new ArrayList<>();
        if (tasks.isEmpty()) {
            return new ArrayList<TacticsHisTaskVO>();
        } else {
            for (TacticsHisTaskEntity task : tasks) {
                TacticsTaskItems hisItem = TacticsTaskItems.builder().taskId(task.getTaskId()).deviceId(task.getDeviceId()).build();
                List<TacticsTaskItems> items = tacticsMapper.selectTacticsHisItems(hisItem);
                TacticsHisTaskVO taskVO = new TacticsHisTaskVO();
                BeanUtils.copyProperties(task, taskVO);
                String deviceName = deviceMapper.selectDeviceById(task.getDeviceId());
                taskVO.setDeviceName(deviceName);
                taskVO.setItems(items);
                taskVOList.add(taskVO);
            }
        }
        return taskVOList;
    }

    @Override
    public List<TacticsNowTaskVO> getNowTask() {
        List<TacticsNowTaskVO> taskVOList = new ArrayList<>();

        String username = SecurityContextHolder.getContext().getAuthentication().getName();
        UserEntity currentUser = userMapper.selectUserByUsername(username);
        ArrayList<String> typeList = new ArrayList<>();
        typeList.add(TacticsType.check.toString());
        typeList.add(TacticsType.lude.toString());
        typeList.add(TacticsType.maintain.toString());
        for (String type : typeList) {
            TacticsNowTaskVO taskVO = new TacticsNowTaskVO();
            String preCode = Objects.equals(type, TacticsType.maintain.toString()) ? "MT" : Objects.equals(type, TacticsType.check.toString()) ? "SC" : "LC";
            taskVO.setCompletedTaskList(tacticsMapper.selectNowHisTask(LocalDate.now(), currentUser.getDeptId(), preCode));
            taskVO.setUncompletedTaskList(tacticsMapper.selectNowTask(currentUser.getDeptId(), preCode));
            taskVO.setType(type);
            taskVO.setDate(LocalDate.now());
            taskVOList.add(taskVO);
        }
        return taskVOList;
    }

    @Override
    public List<TacticsTaskItems> getNowTaskItems(Integer taskId, Integer deviceId) {
        return tacticsMapper.selectTacticsTaskItems(TacticsTaskItems.builder().taskId(taskId).deviceId(deviceId).build());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void sendHisItems(List<TacticsHisTaskItems> itemsList) {
        //item
        tacticsMapper.insertTacticsHisItems(itemsList);
        List<Integer> ids = itemsList.stream().map(TacticsHisTaskItems::getId).toList();
        tacticsMapper.deleteTacticsTaskItemsByIds(ids);
        //task-device
        TacticsTaskDeviceEntity taskDevice = TacticsTaskDeviceEntity.builder().taskId(itemsList.get(0).getTaskId()).deviceId(itemsList.get(0).getDeviceId()).build();
        if (Objects.nonNull(taskDevice)) {
            tacticsMapper.deleteTacticsTaskDeviceByEntity(taskDevice);
        }
        // task
        String username = SecurityContextHolder.getContext().getAuthentication().getName();
        UserEntity currentUser = userMapper.selectUserByUsername(username);
        TacticsTaskEntity task = tacticsMapper.selectTacticstaskById(itemsList.get(0).getTaskId());
        TacticsHisTaskEntity hisTask = new TacticsHisTaskEntity();
        BeanUtils.copyProperties(task, hisTask);
        hisTask.setId(null);
        hisTask.setTaskId(task.getId());
        hisTask.setDeviceId(itemsList.get(0).getDeviceId());
        hisTask.setCompleteTime(LocalDateTime.now());
        hisTask.setCompletedBy(currentUser.getId());
        hisTask.setCompleted("1");
        hisTask.setResult("正常");
        for (TacticsHisTaskItems item : itemsList) {
            if (item.getResult().equals("异常")) {
                hisTask.setResult("异常");
                break;
            }
        }
        tacticsMapper.insertTacticsHisTask(hisTask);
        // 检查task下设备是否已经没有，如果没有，该任务结束，删除任务
        List<TacticsTaskDeviceEntity> tacticsTaskDeviceEntities = tacticsMapper.selectTacticsTaskDevices(TacticsTaskDeviceEntity.builder().taskId(itemsList.get(0).getTaskId()).build());
        if (tacticsTaskDeviceEntities.isEmpty()) {
            tacticsMapper.deleteTacticsTask(itemsList.get(0).getTaskId());
        }

    }

    @Override
    public void changeStatus(List<Integer> ids, String status) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        UserEntity currentUser = userMapper.selectUserByUsername(authentication.getName());
        TacticsEntity tactics = new TacticsEntity();
        tactics.setStatus(status);
        tactics.setUpdateTime(LocalDateTime.now());
        tactics.setUpdateby(currentUser.getId());
        tacticsMapper.updateTacticsStatusByIds(ids, tactics);
    }

    @Override
    public List<TacticsDeviceVO> getTacticsDevices(Integer tacticsId) {
        return tacticsMapper.selectTacticsDevicesWithDeviceName(tacticsId);
    }

    @Override
    public TacticsProjectVO getProjectItems(Integer projectId) {
        TacticsProjectVO tacticsProjectVO = tacticsMapper.selectProjectById(projectId);
        tacticsProjectVO.setItemsList(tacticsMapper.selectItems(projectId));
        return tacticsProjectVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delTacticsByIds(List<Integer> tacticsIds) {
        tacticsMapper.deleteTacticsByIds(tacticsIds);
        tacticsMapper.deleteTacticsDeviceByTacticsIds(tacticsIds);
        tacticsMapper.deleteTacticsProjectByIds(tacticsIds);
    }

    @Override
    public PageResult getTActicsBySearch(TacticsSearchVO tacticsSearchVO, String type) {
        PageHelper.startPage(tacticsSearchVO.getPage(), tacticsSearchVO.getPageSize());
        TacticsEntity tactics = new TacticsEntity();
        tactics.setType(type);
        tactics.setName(tacticsSearchVO.getName());
        tactics.setStartDate(tacticsSearchVO.getStartDate());
        List<TacticsEntity> tacticsEntities = tacticsMapper.selectTactics(tactics);
        PageResult result = new PageResult(tacticsEntities.size(), tacticsEntities);
        return result;
    }

}
